package com.engine4cloud.tdf.education.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.engine4cloud.tdf.common.core.exception.ValidateCodeException;
import com.engine4cloud.tdf.common.data.web.query.Pages;
import com.engine4cloud.tdf.common.data.web.query.Queries;
import com.engine4cloud.tdf.common.data.web.response.PageInfo;
import com.engine4cloud.tdf.common.data.web.response.Params;
import com.engine4cloud.tdf.common.security.service.TdfUser;
import com.engine4cloud.tdf.common.security.util.SecurityUtils;
import com.engine4cloud.tdf.education.convert.PsychologicalCounsellingAttendConvert;
import com.engine4cloud.tdf.education.dto.create.PsychologicalCounsellingAttendCreateDTO;
import com.engine4cloud.tdf.education.dto.query.PsychologicalCounsellingAttendQuery;
import com.engine4cloud.tdf.education.dto.result.PsychologicalCounsellingAttendResultDTO;
import com.engine4cloud.tdf.education.dto.update.PsychologicalCounsellingAttendUpdateDTO;
import com.engine4cloud.tdf.education.entity.PsychologicalCounsellingAttendEntity;
import com.engine4cloud.tdf.education.mapper.PsychologicalCounsellingAttendMapper;
import com.engine4cloud.tdf.education.service.EduPsychologicalCounsellingService;
import com.engine4cloud.tdf.education.service.PsychologicalCounsellingAttendService;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 心理辅导出席表
 *
 * @author wenjie
 * @date 2024-08-13 16:58:05
 */
@Service
public class PsychologicalCounsellingAttendServiceImpl extends ServiceImpl<PsychologicalCounsellingAttendMapper, PsychologicalCounsellingAttendEntity> implements PsychologicalCounsellingAttendService {

    @Lazy
    @Resource
    private EduPsychologicalCounsellingService psychologicalCounsellingService;

    @Override
    public PageInfo<PsychologicalCounsellingAttendResultDTO> pageList(Params pageable, PsychologicalCounsellingAttendQuery dto) {
        IPage<PsychologicalCounsellingAttendEntity> page = super.page(Pages.page(pageable), wrapper(dto));
        return Pages.convert(page, PsychologicalCounsellingAttendConvert.INSTANCE::convert);
    }

    @Override
    public PsychologicalCounsellingAttendResultDTO getById(Long id) {
        return PsychologicalCounsellingAttendConvert.INSTANCE.convert(super.getById(id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateBatch(List<PsychologicalCounsellingAttendUpdateDTO> dto) {
        return updateBatchById(dto.stream().map(PsychologicalCounsellingAttendConvert.INSTANCE::update).toList());
    }

    @Override
    public void batchCreate(String code, List<PsychologicalCounsellingAttendCreateDTO> attendList) {
        if (CollectionUtils.isEmpty(attendList)) {
            return;
        }

        Optional.ofNullable(psychologicalCounsellingService.findByCode(code))
                .orElseThrow(() -> new ValidateCodeException("数据不存在"));

        TdfUser user = SecurityUtils.getUser();
        List<PsychologicalCounsellingAttendEntity> entityList = attendList.stream().map(a -> PsychologicalCounsellingAttendConvert.INSTANCE.create(code, a, user.getTenantId())).toList();

        if (CollectionUtils.isNotEmpty(entityList)) {
            super.saveBatch(entityList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdate(String code, List<PsychologicalCounsellingAttendCreateDTO> attendList) {
        if (CollectionUtils.isEmpty(attendList)) {
            return;
        }

        List<PsychologicalCounsellingAttendEntity> existedList = findListByActivityCode(code);

        //新增
        List<PsychologicalCounsellingAttendEntity> preSavedList = this.preSaveList(code, existedList, attendList);
        if (CollectionUtils.isNotEmpty(preSavedList)) {
            super.saveBatch(preSavedList);
        }

        //删除
        List<Long> preDeleteIdList = this.preDeleteIdList(existedList, attendList);
        if (CollectionUtils.isNotEmpty(preDeleteIdList)) {
            super.removeBatchByIds(preDeleteIdList);
        }
    }

    private List<PsychologicalCounsellingAttendEntity> findListByActivityCode(String activityCode) {
        return super.list(wrapper(new PsychologicalCounsellingAttendQuery(activityCode)));
    }

    private List<PsychologicalCounsellingAttendEntity> preSaveList(String activityCode, List<PsychologicalCounsellingAttendEntity> existedList, List<PsychologicalCounsellingAttendCreateDTO> attendList) {
        if (CollectionUtils.isEmpty(attendList)) {
            return Collections.emptyList();
        }

        TdfUser user = SecurityUtils.getUser();
        Map<String, PsychologicalCounsellingAttendEntity> existMap = existedList.stream().collect(Collectors.toMap(PsychologicalCounsellingAttendEntity::getRybh, Function.identity(), (v1, v2) -> v1));
        return attendList.stream().filter(a -> !existMap.containsKey(a.getRybh())).map(a -> PsychologicalCounsellingAttendConvert.INSTANCE.create(activityCode, a, user.getTenantId())).toList();
    }

    private List<Long> preDeleteIdList(List<PsychologicalCounsellingAttendEntity> existedList, List<PsychologicalCounsellingAttendCreateDTO> modelList) {
        if (CollectionUtils.isEmpty(existedList)) {
            return Collections.emptyList();
        }

        Map<String, PsychologicalCounsellingAttendCreateDTO> modelMap = modelList.stream().collect(Collectors.toMap(PsychologicalCounsellingAttendCreateDTO::getRybh, Function.identity(), (v1, v2) -> v1));
        return existedList.stream().filter(e -> !modelMap.containsKey(e.getRybh())).map(PsychologicalCounsellingAttendEntity::getId).toList();
    }

    private LambdaQueryWrapper<PsychologicalCounsellingAttendEntity> wrapper(PsychologicalCounsellingAttendQuery query) {
        LambdaQueryWrapper<PsychologicalCounsellingAttendEntity> wrapper = Queries.lambda();
        Queries.accept(query.getId(), v -> wrapper.eq(PsychologicalCounsellingAttendEntity::getId, v));
        Queries.accept(query.getFdbh(), v -> wrapper.eq(PsychologicalCounsellingAttendEntity::getFdbh, v));
        Queries.accept(query.getRybh(), v -> wrapper.eq(PsychologicalCounsellingAttendEntity::getRybh, v));
        Queries.accept(query.getXm(), v -> wrapper.like(PsychologicalCounsellingAttendEntity::getXm, v));
        return wrapper;
    }
}